import json, requests, sseclient
import traceback
from datetime import datetime, timedelta

from com.util.loggingUtil import Logs


from com.util.tcp.tcpService import TcpService

from multiprocessing.pool import ThreadPool


def getCompareStockList():
    """
    获取股票代码集合
    :return:
    """
    # 市场类型为1,2,18的
    marketTypes = [1, 2, 18]
    res = []
    for type in marketTypes:
        res += TcpService().getMarketOverview(type)
    return res


# 获取需要的股票代码集合
stock_list = getCompareStockList()


class dongfangcaifu(object):
    """
    东方财富相关抓取接口
    """

    def parseMinute(self, data):
        """
        解析分时数据
        :param data:
        :return:
        """
        self.code = data['code']
        self.market = data['market']
        self.name = data['name']
        self.trends = data['trends']

    def getMinute(self, code, marketType):
        """
        获取分时数据
        :param code:
        :param marketType:
        :return:
        """
        # wogoo对应东方财富映射type
        marketList = {1: '1', 2: '0', 18: '0'}
        dctype = marketList.get(marketType)

        dcTypeDesList = {1: 'sh', 2: 'sz', 18: 'bj'}
        dcTypeDes = dcTypeDesList.get(marketType)

        reqUrl = f"http://91.push2.eastmoney.com/api/qt/stock/trends2/sse?fields1=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f17&fields2=f51,f52,f53,f54,f55,f56,f57,f58&mpi=1000&ut=fa5fd1943c7b386f172d6893dbfba10b&secid={dctype}.{code}&ndays=1&iscr=0&iscca=0&wbp2u=1849325530509956|0|1|0|web"
        reqHeaders = {
            'Accept': 'text/event-stream',
            'Referer':
                f"http://quote.eastmoney.com/concept/{dcTypeDes}{code}.html"
        }

        res = requests.get(reqUrl, stream=True, headers=reqHeaders)
        client = sseclient.SSEClient(res)
        for event in client.events():
            if event.data != '[DONE]':
                res = json.loads(event.data)
                break

        if res['data'] == None:
            return None

        self.parseMinute(res['data'])
        singleData = lambda y: {
            # 收盘
            'close_price': y[2],
            # 成交量
            'trade_amount': int(y[5]) * 100,  # 股数
            # 成交额
            'trade_val': y[6],
            # 均价
            'avg_price': y[7],
        }
        return dict(map(lambda x: (str(x)[11:16], singleData(str(x).split(','))), self.trends))

    def getMinuteDetails(self, code, marketType):
        """
        获取分时明细，比如几份 成交了几手
        :param code:
        :param marketType:
        :return:
        """
        # wogoo对应东方财富映射type
        marketList = {1: '1', 2: '0', 18: '0'}
        dctype = marketList.get(marketType)

        reqUrl = f"http://96.push2.eastmoney.com/api/qt/stock/details/sse?fields1=f1,f2,f3,f4&fields2=f51,f52,f53,f54,f55&mpi=2000&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&pos=-0&secid={dctype}.{code}&wbp2u=|0|0|0|web"
        reqHeaders = {
            'Accept': 'text/event-stream',
            'Referer':
                f"http://quote.eastmoney.com/f1.html?newcode={dctype}.{code}.html"
        }

        res = requests.get(reqUrl, stream=True, headers=reqHeaders)
        client = sseclient.SSEClient(res)
        for event in client.events():
            if event.data != '[DONE]':
                res = json.loads(event.data)
                break

        if res['data'] == None:
            return None

        singleMax_M = 0  # 单笔最大成交量买
        singleMax_S = 0
        all_M = 0
        all_S = 0
        am = {}
        pm = {}
        returnRes = {}
        details = res['data']['details']

        for o in details:
            strs = str(o).split(',')
            timestr = strs[0]  # 时间
            # 过滤盘前
            if timestr <= '09:25:00':
                continue

            price = strs[1]  # 金额
            countNum = int(strs[2])  # 当前成交量
            maxCountNum = int(strs[3])  # 单笔最大成交量
            isRed = strs[4] == '2'  # 红涨绿跌

            splitMinte = 30  # 分隔时间
            startTime = "09:30:00"
            while True:
                splitTime = getTradeTime(startTime, splitMinte)
                key = f"{startTime}-{splitTime}"

                if timestr >= startTime and timestr <= splitTime:
                    tmp_singleMax_M = 0
                    tmp_singleMax_S = 0
                    tmp_all_M = 0
                    tmp_all_S = 0
                    if returnRes.__contains__(key):
                        returnObj = returnRes.get(key)
                        tmp_singleMax_M = returnObj['singleMax_M']
                        tmp_singleMax_S = returnObj['singleMax_S']
                        tmp_all_M = returnObj['all_M']
                        tmp_all_S = returnObj['all_S']

                    if isRed:
                        tmp_singleMax_M += maxCountNum
                        tmp_all_M += countNum
                        singleMax_M += maxCountNum
                        all_M += countNum
                    else:
                        tmp_singleMax_S += maxCountNum
                        tmp_all_S += countNum
                        singleMax_S += maxCountNum
                        all_S += countNum

                    returnRes.__setitem__(key, {'singleMax_M': tmp_singleMax_M, 'singleMax_S': tmp_singleMax_S,
                                                'all_M': tmp_all_M, 'all_S': tmp_all_S})
                startTime = "13:00:00" if splitTime >= "11:30:00" and splitTime <= "13:00:00" else splitTime
                if splitTime >= "15:00:00":
                    break

        if singleMax_S > 0 and all_S > 0:
            sin_v = singleMax_M / singleMax_S
            a_v = all_M / all_S
        else:
            sin_v = 0
            a_v = 0
        day = {"sin_v": sin_v, "a_v": a_v
            , "sin_S": singleMax_S, "sin_M": singleMax_M, "a_S": all_S, "a_M": all_M}

        returnRes.setdefault("day", day)

        return returnRes


Log = Logs("pm")

all_Code = {}


def getTradeTime(startTime, afterMinte):
    if startTime >= "11:30:00" and startTime <= "13:00:00":
        startTime = "13:00:00"
    time_start = datetime.strptime(startTime, "%H:%M:%S")
    time_result = time_start + timedelta(minutes=afterMinte)
    return time_result.strftime("%H:%M:%S")


def df(stockCodeStr):
    try:
        datas = str(stockCodeStr).split(".")
        code = str(datas[0])
        marketType = int(datas[1])

        if code.startswith('5') or code.startswith('15') or code.startswith('16') \
                or code.startswith("68"):
            return
        Log.info(f"开始--{code}")

        rMap = dongfangcaifu().getMinuteDetails(code, marketType)
        Log.info(f"code:{code}:-------\n rMap:{rMap}")
        pm_v = rMap['day']['sin_v']

        if pm_v and pm_v > 1.2:
            Log.info(f"code:{code}:pm_v:{pm_v}")
            all_Code.setdefault(stockCodeStr, pm_v)

    except:
        Log.error(f"code:{stockCodeStr},error{traceback.format_exc()}")


if __name__ == '__main__':
    rMap = dongfangcaifu().getMinuteDetails('001269', 2)
    print(rMap)

    # pool = ThreadPool(8)
    # pool.map(df, stock_list)
    # pool.close()  # 关闭进程池，不再接受新的进程
    # pool.join()  # 主进程阻塞等待子进程的退出
    #
    # resultList = sorted(all_Code.items(), key=lambda kv: (kv[1], kv[0]), reverse=True)
    # Log.info(f"resultList:{resultList}")
    #
    # TcpService().close()
